/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package prj;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;

/**
 *
 * @author ciro
 */
@Stateless
@LocalBean
public class Gestore {

    @EJB
    private RecensioneFacade recensioneFacade;
    @EJB
    private PrenotazioneFacade prenotazioneFacade;
    @EJB
    private LocaleFacade localeFacade;
    @EJB
    private EventoFacade eventoFacade;
    @EJB
    private ClienteFacade clienteFacade;

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    public void registraLocale(String nome,
            String proprietario,
            String indirizzo,
            String telefono,
            String piva,
            String numposti,
            String orario,
            String email,
            String pass,
            String descrizione,
            String immagine) {
        Locale pub = new Locale();
        pub.setId(nome);
        pub.setEmail(email);
        pub.setIndirizzo(indirizzo);
        pub.setNumPosti(Integer.parseInt(numposti));
        pub.setPartitaIVA(piva);
        pub.setOrario(orario);
        pub.setProprietario(proprietario);
        pub.setNumTelefono(telefono);
        pub.setPassword(md5(pass));
        pub.setDescrizione(descrizione);
        pub.setPathImage(immagine);
        //pub.setOpenID(null);
        localeFacade.create(pub);
    }

    public void registraCliente(String nome,
            String cognome,
            String indirizzo,
            String telefono,
            String dataNascita,
            String email,
            String pass) {
        Cliente c = new Cliente();
        c.setId(nome.toLowerCase() + "." + cognome.toLowerCase());
        c.setNome(nome);
        c.setCognome(cognome);
        c.setIndirizzo(indirizzo);
        c.setTelefono(telefono);
        c.setDataNascita(dataNascita);
        c.setEmail(email);
        c.setPassword(md5(pass));
        //c.setOpenID("");        
        clienteFacade.create(c);
    }

    public List<String[]> cerca(String cerca, String table) {
        List<String[]> risultato = new ArrayList<String[]>();
        if (table.equalsIgnoreCase("locale")) {
            List<Locale> locali = localeFacade.findAll();
            Locale l = new Locale();
            for (int i = 0; i < locali.size(); i++) {
                l = locali.get(i);
                if (l.getId().toLowerCase().contains(cerca.toLowerCase())) {
                    String[] temp = {
                        l.getId(),
                        l.getDescrizione(),
                        l.getEmail(),
                        l.getIndirizzo(),
                        String.valueOf(l.getNumPosti()),
                        l.getNumTelefono(),
                        l.getOrario(),
                        l.getPartitaIVA(),
                        l.getPathImage(),
                        l.getProprietario()
                    };
                    risultato.add(temp);
                }
            }
            return risultato;
        } else {
            List<Evento> eventi = eventoFacade.findAll();
            Collections.sort(eventi);
            Evento e = new Evento();
            for (int i = 0; i < eventi.size(); i++) {
                e = eventi.get(i);
                if (e.getId().toLowerCase().contains(cerca.toLowerCase())) {
                    String[] temp = {
                        e.getId(),
                        e.getDataEvento().get(Calendar.DAY_OF_MONTH) + "/" + (e.getDataEvento().get(Calendar.MONTH) + 1) + "/" + e.getDataEvento().get(Calendar.YEAR),
                        e.getDescrizione(),
                        e.getImmagine(),
                        String.valueOf(e.getNumPosti()),
                        e.getLocaleOrganizzatore().getId()
                    };
                    risultato.add(temp);
                }
            }
        }
        return risultato;
    }

    private String md5(String input) {
        MessageDigest m = null;
        try {
            m = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Gestore.class.getName()).log(Level.SEVERE, null, ex);
        }
        m.update(input.getBytes());
        byte[] output = m.digest();
        char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        StringBuilder buf = new StringBuilder();
        for (int j = 0; j < output.length; j++) {
            buf.append(hexDigit[(output[j] >> 4) & 0x0f]);
            buf.append(hexDigit[output[j] & 0x0f]);
        }
        return buf.toString();
    }

    public String login(String user, String password, String utente) {
        if (user == null || password == null || utente == null) {
            return null;
        }
        String pwd = md5(password);
        if (utente != null && utente.equals("cliente")) {
            Cliente cli = clienteFacade.find(user);
            if (cli != null && pwd.equalsIgnoreCase(cli.getPassword())) {
                return user;
            } else {
                return null;
            }
        } else if (utente != null && utente.equals("locale")) {
            Locale loc = localeFacade.find(user);
            if (loc != null && pwd.equalsIgnoreCase(loc.getPassword())) {
                return user;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    public boolean prenota(String tabella, String nome, String cliente, String data, String numPosti) {
        String[] d = data.split("/");
        Calendar c = Calendar.getInstance();
        c.set(Integer.parseInt(d[2]), Integer.parseInt(d[1]) - 1, Integer.parseInt(d[0]));
        if (tabella != null && tabella.equals("locale")) {
            Locale loc = localeFacade.find(nome);
            Cliente cli = clienteFacade.find(cliente);
            int num = Integer.parseInt(numPosti);
            if (loc != null && cli != null) {
                List<Prenotazione> prenotazioni = prenotazioneFacade.findAll();
                int cont = 0;
                Prenotazione temp = new Prenotazione();
                for (int i = 0; i < prenotazioni.size(); i++) {
                    temp = prenotazioni.get(i);
                    if (temp.getLocale().getId().toLowerCase().equals(nome.toLowerCase())
                            && temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) == c.get(Calendar.DAY_OF_MONTH)
                            && temp.getDataPrenotazione().get(Calendar.MONTH) == c.get(Calendar.MONTH)
                            && temp.getDataPrenotazione().get(Calendar.YEAR) == c.get(Calendar.YEAR)) {
                        cont += temp.getNumPostiPrenotati();
                    }
                }
                if (loc.getNumPosti() - cont >= num) {
                    Prenotazione p = new Prenotazione();
                    p.setDataPrenotazione(c);
                    p.setNumPostiPrenotati(num);
                    p.setCliente(cli);
                    p.setLocale(loc);
                    prenotazioneFacade.create(p);
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else if (tabella != null && tabella.equals("evento")) {
            Evento eve = eventoFacade.find(nome);
            Cliente cli = clienteFacade.find(cliente);
            int num = Integer.parseInt(numPosti);
            if (eve != null && cli != null) {
                List<Prenotazione> prenotazioni = prenotazioneFacade.findAll();
                int cont = 0;
                Prenotazione temp = new Prenotazione();
                for (int i = 0; i < prenotazioni.size(); i++) {
                    temp = prenotazioni.get(i);
                    if (temp != null && temp.getEvento() != null
                            && temp.getEvento().getId().toLowerCase().equals(nome.toLowerCase())
                            && temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) == c.get(Calendar.DAY_OF_MONTH)
                            && temp.getDataPrenotazione().get(Calendar.MONTH) == c.get(Calendar.MONTH)
                            && temp.getDataPrenotazione().get(Calendar.YEAR) == c.get(Calendar.YEAR)) {
                        cont += temp.getNumPostiPrenotati();
                    }
                }
                if (eve.getNumPosti() - cont >= num) {
                    Prenotazione p = new Prenotazione();
                    p.setDataPrenotazione(c);
                    p.setNumPostiPrenotati(num);
                    p.setCliente(cli);
                    p.setEvento(eve);
                    p.setLocale(eve.getLocaleOrganizzatore());
                    prenotazioneFacade.create(p);
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public List<String[]> cercaUno(String id, String table) {
        if (table.equalsIgnoreCase("locale")) {
            Locale l = localeFacade.find(id);
            List<Recensione> r = recensioneFacade.findAll();
            Collections.sort(r);
            List<String[]> recensioneFiltered = new ArrayList<String[]>();
            String[] loc = {
                l.getId(),
                l.getDescrizione(),
                l.getEmail(),
                l.getIndirizzo(),
                String.valueOf(l.getNumPosti()),
                l.getNumTelefono(),
                l.getOrario(),
                l.getPartitaIVA(),
                l.getPathImage(),
                l.getProprietario()
            };
            recensioneFiltered.add(loc);
            Recensione temp = new Recensione();
            for (int i = 0; i < r.size(); i++) {
                temp = r.get(i);
                if (temp.getLocaleRecensito().getId().toLowerCase().equals(id.toLowerCase())) {
                    String[] rec = {
                        temp.getDataInserimento().get(Calendar.DAY_OF_MONTH) + "/" + (temp.getDataInserimento().get(Calendar.MONTH) + 1) + "/" + temp.getDataInserimento().get(Calendar.YEAR),
                        temp.getDettagli(),
                        temp.getRecensore().getId(),
                        String.valueOf(temp.getValutazione())
                    };
                    recensioneFiltered.add(rec);
                }
            }

            return recensioneFiltered;
        } else {
            Evento e = eventoFacade.find(id);
            List<String[]> eventoFiltered = new ArrayList<String[]>();
            String[] eve = {
                e.getId(),
                e.getDescrizione(),
                e.getImmagine(),
                e.getDataEvento().get(Calendar.DAY_OF_MONTH) + "/" + (e.getDataEvento().get(Calendar.MONTH) + 1) + "/" + e.getDataEvento().get(Calendar.YEAR),
                String.valueOf(e.getNumPosti()),
                e.getLocaleOrganizzatore().getId(),
                e.getLocaleOrganizzatore().getEmail(),
                e.getLocaleOrganizzatore().getIndirizzo(),
                e.getLocaleOrganizzatore().getNumTelefono(),
                e.getLocaleOrganizzatore().getOrario()
            };
            eventoFiltered.add(eve);

            return eventoFiltered;
        }
    }

    public boolean addRecensione(String nome, String cliente, String dettagli, String valutazione) {
        Calendar c = Calendar.getInstance();
        Locale loc = localeFacade.find(nome);
        Cliente cli = clienteFacade.find(cliente);
        if (loc != null && cli != null) {
            Recensione r = new Recensione();
            r.setDataInserimento(c);
            r.setDettagli(dettagli);
            r.setLocaleRecensito(loc);
            r.setRecensore(cli);
            r.setValutazione(Integer.parseInt(valutazione));
            recensioneFacade.create(r);
            return true;
        } else {
            return false;
        }
    }

    public boolean addEvento(String locale, String nome, String descrizione, String data, int posti, String immagine) {
        String[] d = data.split("/");
        Calendar c = Calendar.getInstance();
        c.set(Integer.parseInt(d[2]), Integer.parseInt(d[1]) - 1, Integer.parseInt(d[0]));
        Locale loc = localeFacade.find(locale);
        if (loc != null) {
            Evento r = new Evento();
            r.setDataEvento(c);
            r.setDescrizione(descrizione);
            r.setId(nome);
            r.setImmagine(immagine);
            r.setLocaleOrganizzatore(loc);
            r.setNumPosti(posti);
            eventoFacade.create(r);
            return true;
        } else {
            return false;
        }
    }

    public List<String[]> visualizzaPrenotazioni(String locale) {
        List<Prenotazione> prenotazioni = prenotazioneFacade.findAll();
        Collections.sort(prenotazioni);
        List<String[]> p = new ArrayList<String[]>();
        Prenotazione temp = new Prenotazione();
        Calendar today = Calendar.getInstance();
        today.set(Calendar.HOUR, 0);
        today.set(Calendar.MINUTE, 0);
        today.set(Calendar.SECOND, 0);
        today.set(Calendar.AM_PM, Calendar.AM);
        today.set(Calendar.MILLISECOND, 0);
        for (int i = 0; i < prenotazioni.size(); i++) {
            temp = prenotazioni.get(i);
            if (temp.getDataPrenotazione().before(today)) {
                prenotazioneFacade.remove(temp);
            } else if (temp.getLocale().getId().equals(locale) && !temp.isEseguita()) {
                if (temp.getEvento() != null) {
                    String[] element = {
                        temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) + "/" + (temp.getDataPrenotazione().get(Calendar.MONTH) + 1) + "/" + temp.getDataPrenotazione().get(Calendar.YEAR),
                        String.valueOf(temp.getNumPostiPrenotati()),
                        temp.getCliente().getNome(),
                        temp.getCliente().getCognome(),
                        temp.getEvento().getId(),
                        String.valueOf(temp.getId())
                    };
                    p.add(element);
                } else {
                    String[] element = {
                        temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) + "/" + (temp.getDataPrenotazione().get(Calendar.MONTH) + 1) + "/" + temp.getDataPrenotazione().get(Calendar.YEAR),
                        String.valueOf(temp.getNumPostiPrenotati()),
                        temp.getCliente().getNome(),
                        temp.getCliente().getCognome(),
                        null,
                        String.valueOf(temp.getId())
                    };
                    p.add(element);
                }
            }
        }
        if (!p.isEmpty()) {
            return p;
        }
        return null;
    }

    public List<String[]> visualizzaPrenotazioniUtente(String user) {
        List<Prenotazione> prenotazioni = prenotazioneFacade.findAll();
        Collections.sort(prenotazioni);
        Calendar today = Calendar.getInstance();
        today.set(Calendar.HOUR, 0);
        today.set(Calendar.MINUTE, 0);
        today.set(Calendar.SECOND, 0);
        today.set(Calendar.AM_PM, Calendar.AM);
        today.set(Calendar.MILLISECOND, 0);
        List<String[]> p = new ArrayList<String[]>();
        Prenotazione temp = new Prenotazione();
        for (int i = 0; i < prenotazioni.size(); i++) {
            temp = prenotazioni.get(i);
            if (temp.getDataPrenotazione().before(today)) {
                prenotazioneFacade.remove(temp);
            } else if (temp.getCliente().getId().equals(user) && !temp.isEseguita()) {
                if (temp.getEvento() != null) {
                    String[] element = {
                        temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) + "/" + (temp.getDataPrenotazione().get(Calendar.MONTH) + 1) + "/" + temp.getDataPrenotazione().get(Calendar.YEAR),
                        String.valueOf(temp.getNumPostiPrenotati()),
                        temp.getLocale().getId(),
                        temp.getEvento().getId(),
                        String.valueOf(temp.getId())
                    };
                    p.add(element);
                } else {
                    String[] element = {
                        temp.getDataPrenotazione().get(Calendar.DAY_OF_MONTH) + "/" + (temp.getDataPrenotazione().get(Calendar.MONTH) + 1) + "/" + temp.getDataPrenotazione().get(Calendar.YEAR),
                        String.valueOf(temp.getNumPostiPrenotati()),
                        temp.getLocale().getId(),
                        null,
                        String.valueOf(temp.getId())
                    };
                    p.add(element);
                }
            }
        }
        if (!p.isEmpty()) {
            return p;
        }
        return null;
    }

    public boolean cambiaStatoPrenotazione(String id) {
        Prenotazione p = prenotazioneFacade.find(Long.parseLong(id));
        if (p == null) {
            return false;
        }
        p.setEseguita(!p.isEseguita());
        return true;
    }

    public void rimuoviPrenotazione(long id) {
        Prenotazione p = prenotazioneFacade.find(id);
        if (p != null) {
            prenotazioneFacade.remove(p);
        }
    }

    public void rimuoviEvento(String id) {
        List<Prenotazione> p = prenotazioneFacade.findAll();
        for (int i = 0; i < p.size(); i++) {
            Prenotazione temp = p.get(i);
            if (temp.getEvento() != null && temp.getEvento().getId().equals(id)) {
                prenotazioneFacade.remove(temp);
            }
        }
        Evento e = eventoFacade.find(id);
        eventoFacade.remove(e);
    }

    public List<String[]> cercaEvento(String localeOrg) {
        List<String[]> risultato = new ArrayList<String[]>();
        List<Evento> eventi = eventoFacade.findAll();
        Collections.sort(eventi);
        Evento e = new Evento();
        for (int i = 0; i < eventi.size(); i++) {
            e = eventi.get(i);
            if (e.getLocaleOrganizzatore().getId().equals(localeOrg)) {
                String[] temp = {
                    e.getId(),
                    e.getDataEvento().get(Calendar.DAY_OF_MONTH) + "/" + (e.getDataEvento().get(Calendar.MONTH) + 1) + "/" + e.getDataEvento().get(Calendar.YEAR),
                    e.getDescrizione(),
                    e.getImmagine(),
                    String.valueOf(e.getNumPosti()),
                    e.getLocaleOrganizzatore().getId()
                };
                risultato.add(temp);
            }
        }
        return risultato;
    }

    public List<String[]> randomLocali() {
        List<Locale> locali = localeFacade.findAll();
        List<String[]> elenco = new ArrayList<String[]>();
        int[] scelta = {-1, -1, -1};
        if (locali.size() <= 3) {
            for (int i = 0; i < locali.size(); i++) {
                scelta[i] = i;
            }
        } else {
            Random r = new Random(Calendar.getInstance().getTimeInMillis());
            for (int i = 0; i < 3; i++) {
                int n = r.nextInt(locali.size());
                while (scelta[0] == n || scelta[1] == n || scelta[2] == n) {
                    n = r.nextInt(locali.size());
                }
                scelta[i] = n;
            }
        }
        for (int i = 0; i < 3; i++) {
            if (scelta[i] != -1) {
                Locale l = locali.get(scelta[i]);
                String[] temp = {
                    l.getId(),
                    l.getPathImage()
                };
                elenco.add(temp);
            }
        }
        return elenco;
    }

    public List<String[]> randomEventi() {
        List<Evento> eventi = eventoFacade.findAll();
        List<String[]> elenco = new ArrayList<String[]>();
        int[] scelta = {-1, -1, -1};
        if (eventi.size() <= 3) {
            for (int i = 0; i < eventi.size(); i++) {
                scelta[i] = i;
            }
        } else {
            Random r = new Random();
            for (int i = 0; i < 3; i++) {
                int n = r.nextInt(eventi.size());
                while (scelta[0] == n || scelta[1] == n || scelta[2] == n) {
                    n = r.nextInt(eventi.size());
                }
                scelta[i] = n;
            }
        }
        for (int i = 0; i < 3; i++) {
            if (scelta[i] != -1) {
                Evento e = eventi.get(scelta[i]);
                String[] temp = {
                    e.getId(),
                    e.getImmagine()
                };
                elenco.add(temp);
            }
        }
        return elenco;
    }
    //List<Evento> eventi = eventoFacade.findAll();
}
